package com.conversationboard.controller;

import java.io.IOException;
import java.security.Principal;
import java.sql.SQLException;
import java.util.Date;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.conversationboard.authenticator.Obfuscator;
import com.conversationboard.cache.ThreadTitleCache;
import com.conversationboard.config.Configuration;
import com.conversationboard.logger.Logger;
import com.conversationboard.model.Board;
import com.conversationboard.model.Boards;
import com.conversationboard.model.Bookmark;
import com.conversationboard.model.Bookmarks;
import com.conversationboard.model.User;
import com.conversationboard.security.EncryptedKey;
import com.conversationboard.security.EncryptionException;

/**
 * Supports both a doGet and a doPost. The GET request is for the AJAX version
 * of it, that doesn't check encryption keys and doesn't redirect you anywhere,
 * since the client doesn't want to move. The doPost is designed to come from
 * the confirm page, and does check the encryption key. I think security is
 * probably not required on bookmarks as it really isn't a big deal.
 * 
 * @author Keith Watson
 * 
 */

@WebServlet(name = "AddBookmarkControllerServlet", urlPatterns = "/AddBookmarkControllerServlet")
public class AddBookmarkControllerServlet extends HttpServlet {

	private static final long serialVersionUID = -1287735758328078968L;


	/**
	 * AJAX request to update bookmark. Fire and forget; does not do any
	 * redirect, since the client is not listening.
	 */

	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");

		// String sid = request.getParameter("sid");
		// sid = Obfuscator.decrypt(sid);
		//
		// if (sid == null) {
		// return;
		// }
		//
		// if (!sid.equals(request.getSession().getId())) {
		// return;
		// }

		try {
			int boardId = Integer.parseInt(request.getParameter("boardid"));
			int threadId = Integer.parseInt(request.getParameter("threadid"));
			int messageCount = Integer.parseInt(request.getParameter("messageid"));

			Principal principal = request.getUserPrincipal();

			if (principal == null) {
				return;
			}

			/* Check authenticity */

			User user = User.get(principal.getName());

			String key = request.getParameter("sid");

			if (key == null) {
				return;
			}

			String decrypted = Obfuscator.decrypt(key);

			if (!decrypted.equals(request.getSession().getId())) {
				return;
			}

			Board board = Boards.getBoard(boardId);

			if (board.isPrivateBoard() && !(user.isMemberOfBoard(boardId))) {
				return;
			}

			Bookmarks bookmarks = user.getBookmarks();
			Bookmark bookmark = new Bookmark();

			/* Work out if it's a new bookmark, or it's one you already have */

			boolean newBookmark = true;

			if (bookmarks.getBookmarks().containsKey(Bookmarks.getKey(boardId, threadId))) {
				newBookmark = false;
			}

			bookmark.setBoardId(boardId);
			bookmark.setThreadId(threadId);
			bookmark.setMessageId(messageCount);
			bookmark.setTitle(ThreadTitleCache.getTitle(boardId, threadId));

			/*
			 * Insert or update the database, based on whether or not it's a new
			 * bookmark
			 */

			if (newBookmark) {
				bookmark.insert(user.getUserId());
			} else {
				bookmark.update(null, user.getUserId());
			}

			bookmarks.add(bookmark);

		} catch (SQLException e) {
			throw new ServletException(e);
		}
	}


	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

		request.setCharacterEncoding("UTF-8");
		response.setCharacterEncoding("UTF-8");

		try {
			int boardId = Integer.parseInt(request.getParameter("boardid"));
			int threadId = Integer.parseInt(request.getParameter("threadid"));
			int messageId = Integer.parseInt(request.getParameter("messageid"));

			Principal principal = request.getUserPrincipal();

			if (principal == null) {
				return;
			}

			/* Check authenticity */

			User user = User.get(principal.getName());

			Board board = Boards.getBoard(boardId);

			if (board.isPrivateBoard() && !(user.isMemberOfBoard(boardId))) {
				return;
			}

			String key = request.getParameter("key");
			EncryptedKey encryptedKey = new EncryptedKey();

			if (!encryptedKey.isValid(key, user.getLoginId())) {
				Logger.log(new Date(), "Security Check Error: " + this.getClass().getName(), user);
				return;
			}

			Bookmarks bookmarks = user.getBookmarks();
			Bookmark bookmark = new Bookmark();

			/* Work out if it's a new bookmark, or it's one you already have */

			boolean newBookmark = true;

			if (bookmarks.getBookmarks().containsKey(Bookmarks.getKey(boardId, threadId))) {
				newBookmark = false;
			}

			bookmark.setBoardId(boardId);
			bookmark.setThreadId(threadId);
			bookmark.setMessageId(messageId);
			bookmark.setTitle(ThreadTitleCache.getTitle(boardId, threadId));

			/*
			 * Insert or update the database, based on whether or not it's a new
			 * bookmark
			 */

			if (newBookmark) {
				bookmark.insert(user.getUserId());
			} else {
				bookmark.update(null, user.getUserId());
			}

			bookmarks.add(bookmark);

			response.sendRedirect(Configuration.getInstance().getRoot() + "/NewAnswersControllerServlet?boardid=" + boardId);

		} catch (EncryptionException e) {
			throw new ServletException(e);
		} catch (SQLException e) {
			throw new ServletException(e);
		}

	}

}
